package main

import (
	"errors"
	"fmt"
	"log"
	"math/rand"
	"sort"
	"time"
)

//定义任务
type Task struct {
	Taskname string
	Content  interface{}
	Date     time.Time
}

func (t *Task) DoTask() {
	fmt.Printf("[task %s done]\n", t.Taskname)
}
func NewTask(Taskname string, Date time.Time) *Task {
	return &Task{Taskname: Taskname, Date: Date}

}

//定义任务队列
type Tasks []*Task

//实现排序接口
func (t *Tasks) Len() int {
	return len(*t)
}
func (t *Tasks) Less(i, j int) bool {
	return (*t)[i].Date.Unix() < (*t)[j].Date.Unix()
}
func (t *Tasks) Swap(i, j int) {
	(*t)[i], (*t)[j] = (*t)[j], (*t)[i]
}
func (t *Tasks) Sort() {
	sort.Sort(t)
}

//实现排序接口

//添加任务
func (t *Tasks) AddTask(taskname string, date time.Time) {
	*t = append(*t, NewTask(taskname, date))
}

//实施任务 从队列中取出最近时间的任务并执行
func (t *Tasks) DoTask() error {
	if t.Len() == 0 {
		fmt.Println("task list is empty")
		return errors.New("task list is empty")
	} else {
		(*t)[0].DoTask()
		*t = (*t)[1:]
		return nil
	}
}

//删除任务 将任务的执行时间设置为time.Unix(0, 0) 并排序 然后踢出队列
func (t *Tasks) DelTask(taskname string) {
	count := 0
	for _, task := range *t {
		if task.Taskname == taskname {
			task.Date = time.Unix(0, 0)
			t.Sort()
			*t = (*t)[1:] //踢出队列
			fmt.Printf("[task %s found and deleted ]\n", taskname)
			count++
		}
	}
	if count == 0 {
		fmt.Printf("[task %s  not found  ]\n", taskname)
	}
	return
}

//获得最近要执行的任务的执行时间
func (t *Tasks) GetlaastTaskruntime() time.Time {
	return (*t)[0].Date
}
func main() {
	//定义一个任务队列
	tasks := make([]*Task, 0, 100)
	tasklist := Tasks(tasks)
	rand.Seed(time.Now().Unix())
	var datelist []time.Time
	for i := 0; i <= 10; i++ {
		date := time.Unix(rand.Int63n(15768000)+1628135974, 0)
		//fmt.Println(date)
		//tasks = append(tasks, NewTask(fmt.Sprint(date), date))
		datelist = append(datelist, date)
		tasklist.AddTask(fmt.Sprint(date), date)
	}
	for i := 0; i < tasklist.Len(); i++ {
		fmt.Println(tasklist[i].Taskname, "++++++", tasklist[i].Date)
	}
	fmt.Println("++++++++++++++++++++++++++++++=")
	//给任务进行排序
	//sort.Sort(Tasks(tasks)
	tasklist.Sort()
	for i := 0; i < tasklist.Len(); i++ {
		fmt.Println(tasklist[i].Taskname, "++++++", tasklist[i].Date)
	}
	for i := 0; i <= 5; i++ {
		if err := tasklist.DoTask(); err != nil {
			log.Println(err)
			break
		}
	}
	fmt.Println("++++++++++++++++++++++++++++++=")
	for i := 0; i < tasklist.Len(); i++ {
		fmt.Println(tasklist[i].Taskname, "++++++", tasklist[i].Date)
	}
	for i := 0; i <= 10; i++ {
		date := time.Unix(rand.Int63n(15768000)+1628135974, 0)
		//fmt.Println(date)
		//tasks = append(tasks, NewTask(fmt.Sprint(date), date))
		//datelist = append(datelist, date)
		tasklist.AddTask(fmt.Sprint(date), date)
	}
	fmt.Println("++++++++++++++++++++++++++++++=")
	for _, date := range datelist {
		tasklist.DelTask(fmt.Sprint(date))
	}

	fmt.Println("++++++++++++++++++++++++++++++=")
	for i := 0; i < tasklist.Len(); i++ {
		fmt.Println(tasklist[i].Taskname, "++++++", tasklist[i].Date)
	}

	//每隔1分钟唤醒一次执行任务
	func() {
		for {
			//取出最近要执行任务的时间跟现在时间做对比 如果小于现在的时间则代表任务要执行 否则 睡一分钟
			if tasklist.GetlaastTaskruntime().Unix() < time.Now().Unix() {
				tasklist.DoTask()
			} else {
				time.Sleep(60 * time.Second)
			}
		}
	}()
	// for i := 0; i <= 10; i++ {
	// 	date := time.Unix(rand.Int63n(15768000)+1628135974, 0)
	// 	//fmt.Println(date)
	// 	tasks = append(tasks, NewTask(fmt.Sprint(date), date))
	// }
	// Tasks(tasks).DoTask()
	// fmt.Println("++++++++++++++++++++++++++++++=")
	// Tasks(tasks).Sort()
	// for i := 0; i < len(tasks); i++ {
	// 	fmt.Println(tasks[i].Taskname, "++++++", tasks[i].Date)
	// }
}
